package com.spring.demo.init.db;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.spring.demo.core.dao.IMemberDao;
import com.spring.demo.core.dao.hibernate.MemberHibernateDao;
import com.spring.demo.core.entity.Member;
import com.spring.demo.core.service.IMemberService;
import com.spring.demo.core.service.impl.MemberHibernateService;

/**
 * hibernate
 * 
 * @author sean
 * 
 */
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:db/jdbcTemplate.properties" })
public class HibernateConfig extends EmbeddedDataSource {

	// hibernate properties
	@Value("${hibernate.dialect}")
	private String HIBERNATE_DIALECT;

	@Value("${hibernate.show_sql}")
	private String HIBERNATE_SHOW_SQL;

	@Value("${hibernate.hbm2ddl.auto}")
	private String HIBERNATE_HBM2DDL_AUTO;

	@Bean
	@Autowired
	public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
		LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
		sessionFactoryBean.setDataSource(dataSource);
		sessionFactoryBean.setAnnotatedClasses(Member.class);
		sessionFactoryBean.setHibernateProperties(hibernateProperties());

		return sessionFactoryBean;
	}

	@Bean(name = "transactionManager")
	@Autowired
	public HibernateTransactionManager transactionManager(
			SessionFactory sessionFactory) {
		HibernateTransactionManager transactionManager = new HibernateTransactionManager(
				sessionFactory);

		return transactionManager;
	}

	@Bean
	public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
		return new PersistenceExceptionTranslationPostProcessor();
	}

	@Bean
	public IMemberService memberService() {
		return new MemberHibernateService();
	}

	@Bean
	public IMemberDao memberDao() {
		return new MemberHibernateDao();
	}

	@Bean
	public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}

	private Properties hibernateProperties() {
		Properties prop = new Properties();
		prop.setProperty("hibernate.dialect", HIBERNATE_DIALECT);
		prop.setProperty("hibernate.show_sql", HIBERNATE_SHOW_SQL);
		prop.setProperty("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);

		return prop;
	}

}
